package com.yequan.mybatisframework.config;

import java.io.InputStream;
import java.util.List;
import java.util.Properties;

import com.yequan.mybatisframework.utils.DocumentUtils;
import com.yequan.mybatisframework.utils.Resources;
import org.apache.commons.dbcp.BasicDataSource;
import org.dom4j.Document;
import org.dom4j.Element;


public class XMLConfigParser {

	private Configuration configuration;

	public XMLConfigParser() {
		configuration = new Configuration();
	}

	/**
	 * 
	 * @param rootElement
	 *            :全局配置文件的根标签<configuration>
	 * @return
	 */
	public Configuration parse(Element rootElement) {
		parseEnvironments(rootElement.element("environments"));
		parseMappers(rootElement.element("mappers"));

		return configuration;
	}

	@SuppressWarnings("unchecked")
	private void parseMappers(Element mappersElement) {
		List<Element> elements = mappersElement.elements("mapper");
		for (Element mapperElement : elements) {
			parseMapper(mapperElement);
		}
	}

	private void parseMapper(Element mapperElement) {
		// 加载mapper映射文件
		String resource = mapperElement.attributeValue("resource");
		InputStream inputStream = Resources.getResourceAsStream(resource);

		Document document = DocumentUtils.readDocument(inputStream);

		XMLMapperParser xmlMapperParser = new XMLMapperParser(configuration);
		// xmlMapperParser会解析出来很多的MappedStatement对象
		xmlMapperParser.parse(document.getRootElement());
	}

	/**
	 * 
	 * @param element：<environments>
	 */
	@SuppressWarnings("unchecked")
	private void parseEnvironments(Element element) {
		String defaultEnvId = element.attributeValue("default");

		List<Element> envElements = element.elements();
		for (Element envElement : envElements) {
			String envId = envElement.attributeValue("id");
			if (envId == null || envId.equals("")) {
				break;
			}
			if (envId.equals(defaultEnvId)) {
				parseDataSource(envElement.element("dataSource"));
			}
		}
	}

	/**
	 * 
	 * @param element：<dataSource>
	 */
	@SuppressWarnings("unchecked")
	private void parseDataSource(Element element) {
		String type = element.attributeValue("type");
		if ("DBCP".equals(type)) {

			Properties properties = new Properties();

			List<Element> elements = element.elements("property");
			for (Element propElement : elements) {
				String name = propElement.attributeValue("name");
				String value = propElement.attributeValue("value");

				properties.put(name, value);
			}

			BasicDataSource dataSource = new BasicDataSource();
			dataSource.setDriverClassName(properties.getProperty("driver"));
			dataSource.setUrl(properties.getProperty("url"));
			dataSource.setUsername(properties.getProperty("username"));
			dataSource.setPassword(properties.getProperty("password"));

			configuration.setDataSource(dataSource);
		}
	}

}
